package com.mnxiaotu.common.security;

import cn.hutool.json.JSONUtil;
import com.mnxiaotu.common.constant.JwtConstant;
import com.mnxiaotu.common.vo.CheckResult;
import com.mnxiaotu.common.vo.Result;
import com.mnxiaotu.util.JwtUtils;
import com.mnxiaotu.util.RedisUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 自定义logout处理
 * @author java1234_小锋 （公众号：java1234）
 */
@Component
public class JwtLogoutSuccessHandler implements LogoutSuccessHandler {

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();

        // 获取 jwt
        String token = httpServletRequest.getHeader("token");
        // 校验jwt
        CheckResult checkResult = JwtUtils.validateJWT(token);
        if(!checkResult.isSuccess()){
            switch(checkResult.getErrCode()){
                case JwtConstant.JWT_ERRCODE_NULL: throw new JwtException("Token 不存在");
                case JwtConstant.JWT_ERRCODE_EXPIRE: throw new JwtException("Token 已过期");
                case JwtConstant.JWT_ERRCODE_FAIL: throw new JwtException("Token 认证失败");
            }
        }
        Claims claims = checkResult.getClaims();
        String username = claims.getSubject();
        // 从redis中删除登录成功后删除的Token
        redisUtil.del(username+":"+"token");

        outputStream.write(JSONUtil.toJsonStr(Result.ok("登出成功")).getBytes());
        outputStream.flush();
        outputStream.close();
    }
}
